package xml;

import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.ArrayList;

import lib.SheetInLib;
import main.ErrorException;

import org.jdom.Document;
import org.jdom.input.SAXBuilder;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;

import define.Config;
import define.ErrorDefine;
import excelBase.ExcelFile;

public class XmlDoc 
{
	private Document m_doc;
	private XmlNode m_root;
	public static ArrayList<ArrayList<XmlNode>> m_deepthList = new ArrayList<>();
	public static ArrayList<Integer> m_maxColumn = new ArrayList<>();
	
	public XmlDoc(XmlNode root)
	{
		m_doc = new Document(root.getElement());
	}
	
	public XmlDoc(String path, int position) throws ErrorException
	{
		readXml(path, position);
		m_deepthList.clear();
		makeChildren();
		m_root.countColumn();
		m_root.countRow();
		adjustColumn();
		makePosition();
	}
	
	public StringBuffer getValue()
	{
		XMLOutputter out = new XMLOutputter();
		out.setFormat(Format.getPrettyFormat());
		return new StringBuffer(out.outputString(m_doc));
	}
	
	public void saveToFile(String path) throws ErrorException
	{
		XMLOutputter out = new XMLOutputter(Format.getPrettyFormat());
		FileOutputStream fos = null;
		try 
		{
			fos = new FileOutputStream(path);
			out.output(m_doc, fos);
		} 
		catch(Exception e) 
		{
			throw new ErrorException(ErrorDefine.E_CANT_WRITE_SCRIPT_ERROR, Config.NO_POSITION);
		}
		finally
		{
			if(fos != null)
			{
				try 
				{
					fos.close();
				} 
				catch (Exception e2)
				{
				}
			}
		}
	}
	
	private void readXml(String path, int position) throws ErrorException
	{
		SAXBuilder builder = new SAXBuilder();
		FileInputStream fis = null;
		try 
		{
			fis = new FileInputStream(path);
			m_doc = builder.build(fis);
		} 
		catch(Exception e) 
		{
			e.printStackTrace();
			throw new ErrorException(ErrorDefine.E_CANT_READ_XML_ERROR, path + ":" + e.getMessage(), position);
		}
		finally
		{
			if(fis != null)
			{
				try 
				{
					fis.close();
				} 
				catch(Exception e2)
				{
				}
			}
		}
	}
	
	private void makeChildren()
	{
		m_root = new XmlNode(m_doc.getRootElement(), 0, null);
		ArrayList<XmlNode> list = new ArrayList<>();
		m_deepthList.add(list);
		list.add(m_root);
		m_root.makeChildren();
	}
	
	private void adjustColumn()
	{
		m_maxColumn.clear();
		for(ArrayList<XmlNode> list: m_deepthList)
		{
			int max = 0;
			for(XmlNode node: list)
			{
				if(node.getColumnNumber() > max)
				{
					max = node.getColumnNumber();
				}
			}
			m_maxColumn.add(max);
			for(XmlNode node: list)
			{
				node.setColumnNumber(max);
			}
		}
	}
	
	private void makePosition()
	{
		m_root.setPosition(0, 0);
		int x = m_root.getColumnNumber();
		int count = 0;
		for(int i = 1, max = m_deepthList.size(); i < max; ++i)
		{
			ArrayList<XmlNode> list = m_deepthList.get(i);	
			for(int j = 0, maxJ = list.size(); j < maxJ; ++j)
			{
				XmlNode node = list.get(j);
				if(j > 0 && node.getFather() == list.get(j - 1).getFather())
				{
					count += list.get(j - 1).getRowNumber();
				}
				else
				{
					count = 0;
				}
				node.setPosition(x, node.getFather().getY() + count);
			}
			x += m_maxColumn.get(i);
		}
	}
	
	public void addToExcel(ExcelFile excel, String sheetName, int position) throws ErrorException
	{
		SheetInLib sheet = excel.addSheet(sheetName, position);
		int column =0;
		int row = m_root.getRowNumber();
		for(int i: m_maxColumn)
		{
			column += i;
		}
		for(int i = 0; i < row; ++i)
		{
			sheet.addRow(i, column, position);
		}
		for(ArrayList<XmlNode> list: m_deepthList)
		{
			for(XmlNode node:list)
			{
				node.toExcel(sheet, position);
			}
		}
		m_deepthList.clear();
		m_maxColumn.clear();
	}
}
